package com.famid.flashcards;

import com.famid.flashcards.animation.DisplayNextView;
import com.famid.flashcards.animation.Flip3dAnimation;
import com.famid.flashcards.animation.SwapViews;
import com.famid.flashcards.data.Card;

import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.PointF;
import android.graphics.RectF;
import android.graphics.Typeface;
import android.graphics.Paint.Style;
import android.text.DynamicLayout;
import android.text.TextPaint;
import android.text.Layout.Alignment;
import android.util.AttributeSet;
import android.util.Log;
import android.view.MotionEvent;
import android.view.View;
import android.view.animation.AccelerateInterpolator;
import android.view.animation.Animation;
import android.widget.Toast;

public class FlashCard extends View {
	private static final String TAG = FlashCard.class.getSimpleName();
	private static float LINE_HEIGHT = .16f; 
	private static float FONT_SIZE = 30;
	
	private Bitmap background;
	private Paint backgroundPaint; 
	
	private RectF cardRect;
	private RectF cardRimRect;
	private Paint cardPaint;
	private Paint cardRimPaint;
	private Paint linePaint;
	private Paint linePaintRed;
	private Paint textPaint;
	private Typeface mFace;
	
	private String cardTitle = "";
	private Card card;
	private boolean showQuestion = true;
	
	private static final int CLICK = 5;
	private PointF start = new PointF();
	private boolean isQuestionCard = true;

	public FlashCard(Context context, AttributeSet attrs, int defStyle) {
		super(context, attrs, defStyle);
		init();
	}

	public FlashCard(Context context, AttributeSet attrs) {
		super(context, attrs);
		init();
	}

	public FlashCard(Context context) {
		super(context);
		init();
	}
	
	public FlashCard(Context context, Card card, String title) {
		super(context);
		this.card = card;
//		this.text = text;
		this.cardTitle = title;
//		this.totalCardNumber = totalCardNumber;
//		this.cardNumber = cardNumber;
//		this.questionCard = questionCard;
		init();
	}
	
	@Override
	public boolean onTouchEvent(MotionEvent event) {
//		Toast.makeText(getContext(), "ssssss", Toast.LENGTH_SHORT).show();
//		return super.onTouchEvent(event);
		
		PointF curr = new PointF(event.getX(), event.getY());
//		Log.d(TAG, "X:"+(curr.x)+" Y:"+curr.y+" H:"+getHeight());
        switch (event.getAction()) {
	        case MotionEvent.ACTION_DOWN:
	        	start.set(event.getX(), event.getY());
	            break;
            case MotionEvent.ACTION_UP:
                int xDiff = (int) Math.abs(curr.x - start.x);
                int yDiff = (int) Math.abs(curr.y - start.y);
                
                if(curr.x > getWidth()*.8125f && curr.y < getHeight()*.1625) {
                	//TODO mark as known if this is answer card
                	Toast.makeText(getContext(), "Mark as known", Toast.LENGTH_SHORT).show();
                }
                else if (xDiff < CLICK && yDiff < CLICK)
                    performClick();
//                Log.d(TAG, "xDiff:"+xDiff+" yDiff:"+yDiff);
                break;
        }
		return true;
	}
	
	private void init() {
//		faceTexture = BitmapFactory.decodeResource(getContext().getResources(), R.drawable.flip_card_background);
//		BitmapShader paperShader = new BitmapShader(faceTexture, Shader.TileMode.MIRROR, Shader.TileMode.MIRROR);
//		setBackgroundColor(Color.GREEN);
		backgroundPaint = new Paint();
		backgroundPaint.setFilterBitmap(true);
		
		cardRect = new RectF(0.01f, 0.00f, 0.984f, 0.995f);
		cardPaint = new Paint();
		cardPaint.setARGB(255, 231, 230, 226);
		
		cardRimRect = new RectF(0.02f, 0.01f, 0.99f, 1f);
		cardRimPaint = new Paint();
		cardRimPaint.setARGB(255, 173, 173, 173);
		
		linePaint = new Paint();
		linePaint.setARGB(255, 204, 207, 215);
		
		linePaintRed = new Paint();
		linePaintRed.setARGB(255, 245, 189, 195);
		linePaintRed.setStyle(Paint.Style.STROKE);
		linePaintRed.setStrokeWidth(0.005f);
		
		textPaint = new Paint();
//		textPaint.setColor(Color.BLACK);
		textPaint.setColor(Color.argb(255, 173, 173, 173));
		textPaint.setTextSize(.08f);
		textPaint.setAntiAlias(true);
		textPaint.setTypeface(Typeface.defaultFromStyle(Typeface.ITALIC));
		
		
		setOnClickListener(new OnClickListener() {
			
			@Override
			public void onClick(View v) {
				if (isQuestionCard) {
					applyRotation(0, 90);
					isQuestionCard = !isQuestionCard;

				} else {
					applyRotation(0, -90);
					isQuestionCard = !isQuestionCard;
				}
			}
		});
		
	}
	
	private void applyRotation(float start, float end) {
		// Find the center of image
		final float centerX = getWidth() / 2.0f;
		final float centerY = getHeight() / 2.0f;

		// Create a new 3D rotation with the supplied parameter
		// The animation listener is used to trigger the next animation
		final Flip3dAnimation rotation = new Flip3dAnimation(start, end, centerX, centerY);
		rotation.setDuration(500);
		rotation.setFillAfter(true);
		rotation.setInterpolator(new AccelerateInterpolator());
		rotation.setAnimationListener(new DisplayNextView(isQuestionCard, this));

		if (isQuestionCard) {
			startAnimation(rotation);
		} else {
			startAnimation(rotation);
		}
	}
	
	@Override
	protected void onDraw(Canvas canvas) {
		drawBackground(canvas);
		canvas.save(Canvas.MATRIX_SAVE_FLAG);
		canvas.scale(getWidth(), getHeight());
		
		drawCard(canvas);
		drawHeader(canvas);
		canvas.restore();
		
		drawText(canvas);
	}
	
	private void drawHeader(Canvas canvas) {
		// TODO Auto-generated method stub
		canvas.drawText(cardTitle, .04f, LINE_HEIGHT-.03f, textPaint);
//		textPaint.setTextSize(.06f);
//		String label = "";
//		
//		canvas.drawText(label, .67f, LINE_HEIGHT-.04f, textPaint);
		
	}

	private void drawCard(Canvas canvas) {
		//Draw card background
		canvas.drawRoundRect(cardRimRect, 0.05f, 0.1f, cardRimPaint);
		canvas.drawRoundRect(cardRect, 0.05f, 0.1f, cardPaint);
		//Draw card lines
		float lineYpos = LINE_HEIGHT;
		for(int i=1;lineYpos*i<1;i++) {
			float y = lineYpos*i;
			if(i==1) {
				canvas.drawLine(0.03f, y, 0.96f, y, linePaintRed);
			}
			else {
				canvas.drawLine(0.03f, y, 0.96f, y, linePaint);
			}
		}
	}
	
	private void drawText(Canvas canvas) {
		Paint textPaint = new Paint();
		textPaint.setColor(Color.BLACK);
		textPaint.setTextSize(FONT_SIZE);
		textPaint.setAntiAlias(true);
//		textPaint.setStrikeThruText(true);
		
		TextPaint tp = new TextPaint(textPaint);
		canvas.translate(getWidth()*.04f, getHeight()*LINE_HEIGHT*2-FONT_SIZE);
		DynamicLayout dl;
		if(showQuestion) {
			dl = new DynamicLayout(card.getQuestion(), tp, (int)(getWidth()*.94f), Alignment.ALIGN_NORMAL, 1, getHeight()*LINE_HEIGHT-FONT_SIZE-5, false);
		}
		else {
			dl = new DynamicLayout(card.getAnswer(), tp, (int)(getWidth()*.94f), Alignment.ALIGN_NORMAL, 1, getHeight()*LINE_HEIGHT-FONT_SIZE-5, false);
		}
			
		dl.draw(canvas);
	}
	

	void drawFont(Canvas canvas, float x, float y, String text, Paint paint, String fontName)
    {
    	 mFace = Typeface.createFromAsset(getContext().getAssets(), fontName);
    	 paint.setTypeface(mFace);
         canvas.drawText(text, x, y, paint);
    }
	
	@Override
	protected void onSizeChanged(int w, int h, int oldw, int oldh) {
		Log.d(TAG, "Size changed to " + w + "x" + h);
		regenerateBackground();
		invalidate();
	}

	private void regenerateBackground() {
		if (background != null) {
			background.recycle();
		}
		Log.d(TAG, "Creating background.");
		
		background = Bitmap.createBitmap(getWidth(), getHeight(), Bitmap.Config.ARGB_8888);
		
		Canvas backgroundCanvas = new Canvas(background);
		float scale = (float) getWidth();		
		backgroundCanvas.scale(scale, scale);
	}
	
	private void drawBackground(Canvas canvas) {
		if (background == null) {
			Log.w(TAG, "Background not created");
		} else {
			canvas.drawBitmap(background, 0, 0, backgroundPaint);
		}
	}
	
	
	@Override
	protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
		int widthMode = MeasureSpec.getMode(widthMeasureSpec);
		int widthSize = MeasureSpec.getSize(widthMeasureSpec);
		
		int heightMode = MeasureSpec.getMode(heightMeasureSpec);
		int heightSize = MeasureSpec.getSize(heightMeasureSpec);
		
		int chosenWidth = chooseDimension(widthMode, widthSize);
		int chosenHeight = chooseDimension(heightMode, heightSize);
		int chosenDimension = Math.min(chosenWidth, chosenHeight);
		
		Log.d(TAG, "Chosen dimesion: " + chosenDimension);
		
		if(chosenWidth > chosenHeight) {
			chosenDimension = chosenHeight;
			setMeasuredDimension((int)(chosenDimension*1.5), chosenDimension);
		}
		else {
			setMeasuredDimension(chosenDimension, (int)(chosenDimension/1.5));
		}
	}
	
	private int chooseDimension(int mode, int size) {
		if (mode == MeasureSpec.AT_MOST || mode == MeasureSpec.EXACTLY) {
			return size;
		} else { // (mode == MeasureSpec.UNSPECIFIED)
			return getPreferredSize();
		} 
	}
	
	// in case there is no size specified
	private int getPreferredSize() {
		return 300;
	}

	public void setShowQuestion(boolean showQuestion) {
		this.showQuestion = showQuestion;
	}
}
